#include <asm.h>
#include <regdef.h>
#include <inst_test.h>

LEAF(n76_dcacop_op0)
    addi.w    s0, s0, 0x1
    add.w     s2, zero, zero

    la.local  t7, start
start:

    li      t0, 0xd0100000
    li      t1, 0xffffffff
    st.w    t1, t0, 0x0

# set up the inst DMW, let the MAT=01(Coherent Cached)
    li        t1, 0xe0000000
    and       t1, t7, t1
    srli.w    t2, t1, 0x4
    li        t3, 0x11
    or        t1, t1, t2
    or        t1, t1, t3
    csrwr     t1, csr_dmw1
    invtlb    0x0, zero, zero

    li        t7, 0xd0100000
# set up the inst DMW, let the MAT=01(Coherent Cached)
    li        t1, 0xe0000000
    and       t1, t7, t1
    srli.w    t2, t1, 0x4
    li        t3, 0x11
    or        t1, t1, t2
    or        t1, t1, t3
    csrwr     t1, csr_dmw0
    invtlb    0x0, zero, zero

# set up the CRMD, let DA=0, PG=1, and PRL=0
    //let DA=0 and PG=1 and prl=0
    li      t0, 0x10
    li      t1, 0x1f
    csrxchg t0, t1, csr_crmd 

    li      t0, 0xd0100000
    ld.w    t1, t0, 0x0

# set up the DMW, let the MAT=00(Strongly-Ordered UnCached)
    li        t1, 0xe0000000
    and       t1, t7, t1
    srli.w    t2, t1, 0x4
    li        t3, 0x1
    or        t1, t1, t2
    or        t1, t1, t3
    csrwr     t1, csr_dmw0
    invtlb    0x0, zero, zero
    
# bypass the dcacop and directly write to the physical memory
    li        t0, 0xd0100000
    li        t1, 0x00000000 
    st.w      t1, t0, 0x0

# invalid the old data in dcache
    
    li        t0, 0xd0100000

    li        t1, 0xffffffff
    slli.w    t1, t1, OFFSET
    li        t2, 0xffffffff
    slli.w    t2, t2, OFFSET+INDEX
    li        t3, 0x0
    nor       t2, t3, t2
    and       t1, t1, t2

    and       t0, t0, t1

    li        t1, 0x0
    li        t2, WAY

invalid_cache_line: 
    cacop     0x01, t0, 0x0 
    addi.w    t0, t0, 0x1
    addi.w    t1, t1, 0x1
    bne       t1, t2, invalid_cache_line

# set up the DMW, let the MAT=01(Coherent Cached)
    li        t1, 0xe0000000
    and       t1, t7, t1
    srli.w    t2, t1, 0x4
    li        t3, 0x11
    or        t1, t1, t2
    or        t1, t1, t3
    csrwr     t1, csr_dmw0
    invtlb    0x0, zero, zero

    li        t0, 0xd0100000
    ld.w      t1, t0, 0x0
    li        t2, 0x00000000
    bne       t1, t2, inst_error

inst_pass:
###detect exception
    bne s2, zero, inst_error
###score ++
    addi.w    s3, s3, 0x1
###output
inst_error:
    li        t0, 0x8 
    li        t1, 0x1f 
    csrxchg   t0, t1, csr_crmd

    slli.w    t1, s0, 24
    or        t0, t1, s3
    st.w      t0, s1, 0x0
    jirl      zero, ra, 0x0
END(n76_dcacop_op0)
